package com.ibeeking.found.upms.b.rest.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ibeeking.found.common.base.BaseDO;
import com.ibeeking.found.common.constants.RoleConstant;
import com.ibeeking.found.common.enums.PublishStatusEnum;
import com.ibeeking.found.common.utils.UserUtils;
import com.ibeeking.found.upms.b.rest.service.ICpRoleService;
import com.ibeeking.found.upms.b.rest.service.ICpUserRoleService;
import com.ibeeking.found.upms.service.common.bo.CpRoleBO;
import com.ibeeking.found.upms.service.common.bo.CpUserRoleBO;
import com.ibeeking.found.upms.service.common.dos.CpRoleDO;
import com.ibeeking.found.upms.service.common.param.CpRoleParam;
import com.ibeeking.found.upms.service.common.query.CpRolePageQuery;
import com.ibeeking.found.upms.service.common.vo.CpRolePageVO;
import com.ibeeking.found.upms.service.common.vo.CpRoleVO;
import com.ibeeking.found.upms.service.mapper.CpRoleMapper;
import com.ibeeking.nematos.core.utils.SpringBeanUtil;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.data.StringUtils;
import com.ibeeking.nematos.utils.json.JsonUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName OriginalShopRoleServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2021-04-15 11:46
 **/
@Service
public class CsRoleSperviceImpl implements ICpRoleService {

    @Resource
    private CpRoleMapper cpRoleMapper;
    @Resource
    private ICpUserRoleService cpUserRoleServiceImpl;

    @Override
    public Page<CpRolePageVO> pageList(CpRolePageQuery query) {
        LambdaQueryWrapper<CpRoleDO> queryWrapper = new LambdaQueryWrapper<>(CpRoleDO.class);
        queryWrapper
                .orderByAsc(CpRoleDO::getSort)
                .orderByDesc(BaseDO::getCreateTime)
                .eq(null != query.getPublishStatus(), CpRoleDO::getPublishStatus, query.getPublishStatus())
                .eq(StringUtils.isNotBlank(query.getCode()), CpRoleDO::getCode, query.getCode())
                .like(StringUtils.isNotBlank(query.getName()), CpRoleDO::getName, query.getName())
        ;
        Page<CpRoleDO> page = cpRoleMapper.selectPage(new Page<>(query.getPageNum(), query.getPageSize()), queryWrapper);
        Page<CpRolePageVO> result = BeanUtil.convertPage(page, CpRolePageVO.class);
        List<CpRolePageVO> records = result.getRecords();
        if (!Collections3.isEmpty(records)) {
            List<Long> roleIds = records.stream().map(CpRolePageVO::getId).collect(Collectors.toList());
            List<CpUserRoleBO> csUserRoleBos = cpUserRoleServiceImpl.queryUserIdsByRoleIds(roleIds);
            Map<Long, List<CpUserRoleBO>> roleMap = csUserRoleBos.stream().collect(Collectors.groupingBy(CpUserRoleBO::getRoleId));
            records.stream().forEach(s -> {
                if (roleMap.containsKey(s.getId())) {
                    s.setCount(roleMap.get(s.getId()).size());
                } else {
                    s.setCount(0);
                }
            });
        }
        return result;
    }

    @Override
    public Boolean add(CpRoleParam param) {
        CpRoleDO roleDO = BeanUtil.convertBean(param, CpRoleDO.class);
        if (!checkUnique(roleDO)) {
            //throw new BusinessException("当前角色编码或名称已存在");
            throw new BusinessException("当前角色名称已存在");
        }
        roleDO.setCode("");
        roleDO.setCreateBy(UserUtils.getUserId());
        roleDO.setCreateTime(LocalDateTime.now());
        roleDO.setModifyTime(LocalDateTime.now());
        return cpRoleMapper.insert(roleDO) > 0;
    }

    @Override
    public Boolean modify(CpRoleParam param) {
        CpRoleDO roleDO = BeanUtil.convertBean(param, CpRoleDO.class);
        if (!checkUnique(roleDO)) {
            //throw new BusinessException("当前角色编码或名称已存在");
            throw new BusinessException("当前角色名称已存在");
        }
        roleDO.setCode(null);
        roleDO.setModifyBy(UserUtils.getUserId());
        roleDO.setModifyTime(LocalDateTime.now());
        return cpRoleMapper.updateById(roleDO) > 0;
    }

    @Override
    public CpRoleVO view(Long id) {
        CpRoleBO roleBO = getBean().queryById(id);
        return BeanUtil.convertBean(roleBO, CpRoleVO.class);
    }

    @Override
    public CpRoleBO queryById(Long id) {
        CpRoleDO roleDO = cpRoleMapper.selectById(id);
        return BeanUtil.convertBean(roleDO, CpRoleBO.class);
    }

    @Override
    public Boolean changeStatus(Long id, Integer status) {
        CpRoleDO roleDO = new CpRoleDO();
        roleDO.setId(id);
        roleDO.setPublishStatus(status);
        if (RoleConstant.ADMINISTRATOR.equals(getBean().queryById(id).getCode()) && PublishStatusEnum.DISABLE.getValue().equals(status)) {
            throw new BusinessException("超级管理员不允许禁用");
        }
        roleDO.setModifyBy(UserUtils.getUserId());
        roleDO.setModifyTime(LocalDateTime.now());
        return cpRoleMapper.updateById(roleDO) > 0;
    }

    @Override
    public Boolean del(Long id) {
        CpRoleBO roleBO = getBean().queryById(id);
        if (null == roleBO) {
            return true;
        }
        if (RoleConstant.ADMINISTRATOR.equals(roleBO.getCode())) {
            throw new BusinessException("超级管理员不允许删除");
        }
        if (PublishStatusEnum.ENABLE.getValue().equals(roleBO.getPublishStatus())) {
            throw new BusinessException("请先禁用后再删除");
        }
        cpUserRoleServiceImpl.delByRoleId(id);
        return cpRoleMapper.deleteById(id) > 0;
    }

    @Override
    public Long selectAdministratorId() {
        CpRoleDO roleDO = cpRoleMapper.selectOne(new LambdaQueryWrapper<>(CpRoleDO.class).eq(CpRoleDO::getCode, RoleConstant.ADMINISTRATOR));
        return roleDO.getId();
    }

    @Override
    public List<CpRoleBO> queryByIds(List<Long> ids) {
        List<CpRoleDO> csRoleDos = cpRoleMapper.selectBatchIds(ids);
        if (Collections3.isEmpty(csRoleDos)) {
            return Collections3.emptyList();
        }
        return JsonUtils.jsonToList(csRoleDos.stream().filter(s -> PublishStatusEnum.ENABLE.getValue().equals(s.getPublishStatus())).collect(Collectors.toList()), CpRoleBO.class);
    }


    private static ICpRoleService getBean() {
        return SpringBeanUtil.getBean(ICpRoleService.class);
    }

    private Boolean checkUnique(CpRoleDO roleDO) {
        Integer count = cpRoleMapper.selectCount(new LambdaQueryWrapper<>(CpRoleDO.class)
                .ne(null != roleDO.getId(), CpRoleDO::getId, roleDO.getId())
                .and(
                        Wrapper -> Wrapper
                                /*.eq(StringUtils.isNotBlank(roleDO.getCode()), CsRoleDO::getCode, roleDO.getCode())
                                .or()*/
                                .eq(StringUtils.isNotBlank(roleDO.getName()), CpRoleDO::getName, roleDO.getName())
                )
        );
        return 0 == count;
    }
}
